﻿#region Using Statements

#endregion

namespace DirectZZT.Shared.World.Objects
{
    /// <summary>
    /// Specifies the fundamental sky directions.
    /// </summary>
    public enum Direction
    {
        /// <summary>
        /// Default value.
        /// </summary>
        None = 0,
        /// <summary>
        /// North.
        /// </summary>
        North,
        /// <summary>
        /// South.
        /// </summary>
        South,
        /// <summary>
        /// East.
        /// </summary>
        East,
        /// <summary>
        /// West.
        /// </summary>
        West
    }

    /// <summary>
    /// Provides extension methods for the <see cref="Direction"/> enumeration.
    /// </summary>
    public static class DirectionExtensions
    {
        /// <summary>
        /// Returns the direction that is the current direction inverted.
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static Direction Invert(this Direction direction)
        {
            if (direction == Direction.North) { return Direction.South; }
            if (direction == Direction.East) { return Direction.West; }
            if (direction == Direction.South) { return Direction.North; }
            if (direction == Direction.West) { return Direction.East; }
            return Direction.None;
        }

        /// <summary>
        /// Returns the delta for X that must be moved into the given direction.
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static int GetDeltaX(this Direction direction)
        {
            switch (direction)
            {
                case Direction.North: return 0;
                case Direction.East: return 1;
                case Direction.South: return 0;
                case Direction.West: return -1;
                default: return 0;
            }
        }

        /// <summary>
        /// Returns the delta for Y that must be moved into the given direction.
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static int GetDeltaY(this Direction direction)
        {
            switch (direction)
            {
                case Direction.North: return -1;
                case Direction.East: return 0;
                case Direction.South: return 1;
                case Direction.West: return 0;
                default: return 0;
            }
        }

        /// <summary>
        /// Returns the direction of the given deltaX and deltaY values.
        /// </summary>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static Direction GetDirection(int dx, int dy)
        {
            if (dx == 1 && dy == 0) { return Direction.East; }
            if (dx == -1 && dy == 1) { return Direction.West; }
            if (dx == 0 && dy == 1) { return Direction.South; }
            if (dx == 0 && dy == -1) { return Direction.North; }
            // invalid case
            return Direction.None;
        }
    }
}
